#include "buffer.h"
#include <errno.h>
#include <sys/types.h>
#include <sys/uio.h>
#include <unistd.h>

/*
    从fd上读取数据据 Poller工作在LT模式
    Buffer缓冲去是有大小的，但是从fd上读取数据的时候也，却不知道tcp数据最终的位置
*/

ssize_t Buffer::read_fd(int fd, int *save_errno) {
    char extrabuf[65536] = {0}; // 栈上的内存空间64K


    struct iovec vec[2];

    const size_t writable = writable_bytes(); // 这是buffer底层缓冲区剩余的可写空间大小
    vec[0].iov_base = begin() + writer_index_;
    vec[0].iov_len = writable;

    vec[1].iov_base = extrabuf;
    vec[1].iov_len = sizeof extrabuf;

    const int iovcnt = (writable < sizeof extrabuf) ? 2 : 1;
    const ssize_t n = ::readv(fd, vec, iovcnt);
    if (n < 0) {
        *save_errno = errno;
    } else if (n <= writable) {
        writer_index_ += n;
    } else { // extrabuf里面也卸了数据
        writer_index_ = buffer_.size();
        append(extrabuf, n - writable); // writer_index_开始写n-writable大小的数据
    }
    return n;
}

ssize_t Buffer::write_fd(int fd, int *save_errno) {
    ssize_t n = ::write(fd, peek(), readable_bytes());
    if (n < 0) {
        *save_errno = errno;
    }
    return n;
}